﻿using System.Dynamic;
using Basic.FormCollect.Model;
using Basic.FormExtendService;
using Basic.FormRemoteModel;
using Basic.UserFormService.Interface;
using Basic.UserFormService.PhysicsTable.Model;
using WeDonekRpc.Helper;

namespace Basic.UserFormService.lmpl
{
    internal class PhysicsQueryFillService : IPhysicsQueryFillService
    {
        private readonly IEmpService _Emp;
        private readonly IUnitDeptService _Dept;
        private readonly IDictItemService _DictItem;
        private readonly ITreeDicService _TreeDic;

        public PhysicsQueryFillService (
            IEmpService emp,
            IUnitDeptService unitDept,
            IDictItemService dictItem,
            ITreeDicService treeDic )
        {
            this._Emp = emp;
            this._Dept = unitDept;
            this._DictItem = dictItem;
            this._TreeDic = treeDic;
        }

        private List<long> _deptId;
        private List<long> _empId;
        private List<long> _unitDeptId;
        private Dictionary<long, List<string>> _dictVal;
        private Dictionary<long, List<string>> _treeDict;

        public void InitRows ( ExpandoObject[] rows, PhyExtendCol[] cols )
        {
            IDictionary<string, object>[] dic = this.Load(rows, cols);
            PhysicsExtendVal vals = this._GetExtendVal();
            dic.ForEach(row =>
            {
                cols.ForEach(c =>
                {
                    this.SetValue(c, row, vals);
                });
            });
        }
        private void _Init ()
        {
            if ( _deptId == null )
            {
                this._deptId = new List<long>();
                this._empId = new List<long>();
                this._dictVal = new Dictionary<long, List<string>>();
                this._treeDict = new Dictionary<long, List<string>>();
                this._unitDeptId = new List<long>();
            }
        }
        public PhysicsExtendVal GetExtendVal ()
        {
            if ( this._empId.Count == 0 && this._deptId.Count == 0 && this._unitDeptId.Count == 0 && this._treeDict.Count == 0 && this._dictVal.Count == 0 )
            {
                return null;
            }
            PhysicsExtendVal val = new PhysicsExtendVal();
            if ( this._empId.Count > 0 )
            {
                val.Emp = this._Emp.GetEmpName(this._empId.Distinct().ToArray());
            }
            if ( this._deptId.Count > 0 )
            {
                val.Dept = this._Dept.GetNames(this._deptId.Distinct().ToArray());
            }
            if ( this._unitDeptId.Count > 0 )
            {
                val.DeptUnit = this._Dept.GetUnitDeptName(this._unitDeptId.Distinct().ToArray());
            }
            if ( this._treeDict.Count > 0 )
            {
                val.TreeItem = this._TreeDic.GetNames(this._treeDict.ToDictionary(a => a.Key, a => a.Value.Distinct().ToArray()));
            }
            if ( this._dictVal.Count > 0 )
            {
                val.DictItem = this._DictItem.GetNames(this._dictVal.ToDictionary(a => a.Key, a => a.Value.Distinct().ToArray()));
            }
            return val;
        }
        public IDictionary<string, object> Load ( ExpandoObject data, PhyExtendCol[] cols )
        {
            if ( data == null )
            {
                return null;
            }
            this._Init();
            IDictionary<string, object> row = data;
            cols.ForEach(c =>
            {
                if ( c.Mode == PhyColShowMode.DeptName || c.Mode == PhyColShowMode.DeptAndUnit || c.Mode == PhyColShowMode.UnitName )
                {
                    if ( row.TryGetValue(c.ColName, out object val) && val != null )
                    {
                        this._deptId.Add(Convert.ToInt64(val));
                    }
                }
                else if ( c.Mode == PhyColShowMode.DeptAndUnit )
                {
                    if ( row.TryGetValue(c.ColName, out object val) && val != null )
                    {
                        this._unitDeptId.Add(Convert.ToInt64(val));
                    }
                }
                else if ( c.Mode == PhyColShowMode.EmpName )
                {
                    if ( row.TryGetValue(c.ColName, out object val) && val != null )
                    {
                        this._empId.Add(Convert.ToInt64(val));
                    }
                }
                else if ( c.Mode == PhyColShowMode.DictItemName )
                {
                    List<string> vals = this._dictVal.GetOrAdd(c.DictId.Value, a => new List<string>());
                    if ( row.TryGetValue(c.ColName, out object val) && val != null )
                    {
                        vals.Add(val.ToString());
                    }
                }
                else if ( c.Mode == PhyColShowMode.DictTreeName )
                {
                    List<string> vals = this._treeDict.GetOrAdd(c.DictId.Value, a => new List<string>());
                    if ( row.TryGetValue(c.ColName, out object val) && val != null )
                    {
                        vals.Add(val.ToString());
                    }
                }
            });
            return row;
        }
        public void SetValue ( PhyExtendCol col, IDictionary<string, object> row, PhysicsExtendVal val )
        {
            if ( col.Mode == PhyColShowMode.EmpName )
            {
                if ( row.TryGetValue(col.ColName, out object value) && value != null )
                {
                    long id = Convert.ToInt64(value);
                    row.Add(col.Name, val.Emp.GetValueOrDefault(id));
                }
            }
            else if ( col.Mode == PhyColShowMode.DictItem )
            {
                if ( row.TryGetValue(col.ColName, out object value) )
                {
                    string key = value == null ? string.Empty : Convert.ToString(value);
                    row.Add(col.Name, col.Items.GetValueOrDefault(key));
                }
            }
            else if ( col.Mode == PhyColShowMode.DeptName || col.Mode == PhyColShowMode.UnitName )
            {
                if ( row.TryGetValue(col.ColName, out object value) && value != null )
                {
                    long id = Convert.ToInt64(value);
                    row.Add(col.Name, val.Dept.GetValueOrDefault(id));
                }
            }
            else if ( col.Mode == PhyColShowMode.DeptAndUnit )
            {
                if ( row.TryGetValue(col.ColName, out object value) && value != null )
                {
                    long id = Convert.ToInt64(value);
                    row.Add(col.Name, val.DeptUnit.GetValueOrDefault(id));
                }
            }
            else if ( col.Mode == PhyColShowMode.DictTreeName )
            {
                if ( row.TryGetValue(col.ColName, out object value) && value != null )
                {
                    string id = Convert.ToString(value);
                    row.Add(col.Name, val.TreeItem.Find(c => c.DicId == col.DictId && c.DicValue == id, c => c.DicText));
                }
            }
            else if ( col.Mode == PhyColShowMode.DictItemName )
            {
                if ( row.TryGetValue(col.ColName, out object value) && value != null )
                {
                    string id = Convert.ToString(value);
                    row.Add(col.Name, val.DictItem.Find(c => c.DicId == col.DictId && c.DicValue == id, c => c.DicText));
                }
            }
        }

        private PhysicsExtendVal _GetExtendVal ()
        {
            if ( this._empId.Count == 0 && this._deptId.Count == 0 && this._unitDeptId.Count == 0 && this._treeDict.Count == 0 && this._dictVal.Count == 0 )
            {
                return null;
            }
            PhysicsExtendVal val = new PhysicsExtendVal();
            if ( this._empId.Count > 0 )
            {
                val.Emp = this._Emp.GetEmpName(this._empId.Distinct().ToArray());
            }
            if ( this._deptId.Count > 0 )
            {
                val.Dept = this._Dept.GetNames(this._deptId.Distinct().ToArray());
            }
            if ( this._unitDeptId.Count > 0 )
            {
                val.DeptUnit = this._Dept.GetUnitDeptName(this._unitDeptId.Distinct().ToArray());
            }
            if ( this._treeDict.Count > 0 )
            {
                val.TreeItem = this._TreeDic.GetNames(this._treeDict.ToDictionary(a => a.Key, a => a.Value.Distinct().ToArray()));
            }
            if ( this._dictVal.Count > 0 )
            {
                val.DictItem = this._DictItem.GetNames(this._dictVal.ToDictionary(a => a.Key, a => a.Value.Distinct().ToArray()));
            }
            return val;
        }
        public IDictionary<string, object>[] Load ( ExpandoObject[] list, PhyExtendCol[] cols )
        {
            if ( list.IsNull() )
            {
                return null;
            }
            this._Init();
            IDictionary<string, object>[] rows = list.ConvertAll(c => (IDictionary<string, object>)c);
            rows.ForEach(a =>
            {
                cols.ForEach(c =>
                {
                    if ( c.Mode == PhyColShowMode.DeptName || c.Mode == PhyColShowMode.DeptAndUnit || c.Mode == PhyColShowMode.UnitName )
                    {
                        if ( a.TryGetValue(c.ColName, out object val) && val != null )
                        {
                            this._deptId.Add(Convert.ToInt64(val));
                        }
                    }
                    else if ( c.Mode == PhyColShowMode.DeptAndUnit )
                    {
                        if ( a.TryGetValue(c.ColName, out object val) && val != null )
                        {
                            this._unitDeptId.Add(Convert.ToInt64(val));
                        }
                    }
                    else if ( c.Mode == PhyColShowMode.EmpName )
                    {
                        if ( a.TryGetValue(c.ColName, out object val) && val != null )
                        {
                            this._empId.Add(Convert.ToInt64(val));
                        }
                    }
                    else if ( c.Mode == PhyColShowMode.DictItemName )
                    {
                        List<string> vals = this._dictVal.GetOrAdd(c.DictId.Value, a => new List<string>());
                        if ( a.TryGetValue(c.ColName, out object val) && val != null )
                        {
                            vals.Add(val.ToString());
                        }
                    }
                    else if ( c.Mode == PhyColShowMode.DictTreeName )
                    {
                        List<string> vals = this._treeDict.GetOrAdd(c.DictId.Value, a => new List<string>());
                        if ( a.TryGetValue(c.ColName, out object val) && val != null )
                        {
                            vals.Add(val.ToString());
                        }
                    }
                });
            });
            return rows;
        }

    }
}
